package thread

import (
	"time"

	"gitee.com/sansaniot/ssiot-core/facade/env"
	"gitee.com/sansaniot/ssiot-core/facade/runtime"
	"gitee.com/sansaniot/ssiot-core/logger"
	"gorm.io/gorm"

	"ssnotify/common/constant"
	"ssnotify/common/dto"
	"ssnotify/internal/notify/models"
)

type NotifyRecordThread struct {
}

func (NotifyRecordThread) Run(threadName string) {
	go func() {
		produceT := time.NewTicker(5 * time.Millisecond)
		consumeT := time.NewTicker(15 * time.Second)
		defer produceT.Stop()
		defer consumeT.Stop()
		dataList := make([]interface{}, 0)
		for {
			select {
			case <-produceT.C:
				// 不停地写到dataList
				s := constant.RecordNotifyQueue.Dequeue()
				if s != nil {
					dataList = append(dataList, s)
				}
			case <-consumeT.C:
				if len(dataList) > 0 {
					// 批量处理数据
					notifyRecords(dataList)
					// 清空(减少扩容)
					dataList = dataList[0:0]
				}
			}
		}
	}()
}

func notifyRecords(dataList []interface{}) {
	db := runtime.Runtime.GetDbByKey("db")
	if db == nil {
		return
	}
	notifyRecordModel := &models.NotifyRecord{}
	notifyRecordModel.Orm = db
	insertList := make([]models.NotifyRecord, 0)
	userRecords := make(map[string]int)
	for _, v := range dataList {
		if record, ok := v.(models.NotifyRecord); ok {
			insertList = append(insertList, record)
			// 统计明细
			userRecords[record.UserId]++
		}
		if len(insertList) > 5000 {
			if err := notifyRecordModel.Add(&insertList); err != nil {
				logger.Error(err)
			}
			insertList = make([]models.NotifyRecord, 0)
		}
	}

	if len(insertList) > 0 {
		if err := notifyRecordModel.Add(&insertList); err != nil {
			logger.Error(err)
		}
	}
	logger.Info("通知记录入库.")
	addToDataDetail(db, userRecords)
}

func addToDataDetail(db *gorm.DB, userRecords map[string]int) {
	sysDataDetailModel := &models.SysDataDetail{}
	sysDataDetailModel.Orm = db
	for uid, cnt := range userRecords {
		if err := sysDataDetailModel.Add(&models.SysDataDetail{
			Type:       "DATA_NOTIFY_NUM",
			Key:        uid,
			Value:      cnt,
			CreateTime: dto.LocalTime(time.Now()),
		}); err != nil {
			env.Log.Error(err)
		}
	}
}
